package com.alibaba.citrus.ots.b2b.trade.order.functions.order.entity;

import com.alibaba.citrus.ots.b2b.trade.order.facade.common.SetOrderTag;
import com.alibaba.citrus.ots.b2b.trade.order.repository.*;
import com.alibaba.citrus.ots.common.annotation.EpochTransactional;
import com.alibaba.citrus.ots.common.annotation.FunctionInvoker;
import com.alibaba.citrus.ots.common.constant.SaleOrderConstants;
import com.alibaba.citrus.ots.common.exception.FunctionException;
import com.alibaba.citrus.ots.common.util.SpringContextUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.db.service.CustomSequenceAccessor;
import com.alibaba.lattice2.epoch.middleware.mq.runtime.EpochMessageService;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.contants.BcOtsConstants;
import com.epoch.app.otsb2btradecenter.dto.response.BatchCreateOrderResponse;
import com.epoch.app.otsb2btradecenter.enums.OrderStatus;
import com.epoch.app.otsb2btradecenter.model.dto.TradeMessageSDO;
import com.epoch.app.otsb2btradecenter.sdo.OrderLineSDO;
import com.epoch.app.otsb2btradecenter.sdo.OrderSDO;
import com.epoch.app.otspricecenter.api.creditquery.service.CreditQueryService;
import com.epoch.app.otsunifiedinventory.model.dto.GetListWarehouseStockRequest;
import com.epoch.app.otsunifiedinventory.model.dto.WarehouseInventory;
import com.epoch.app.otsunifiedinventory.service.OtsUnifiedInventoryService;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Getter
public class OrderWriteEntity {

    private static final String TYPE = "1";

    private static final String FIXED_VALUE = "10";

    private static final String RETURN_FLAG = "1";

    private OrderSDO orderSDO;

    private static OrderWriteRepository orderWriteRepository;
    private static OrderLineWriteRepository orderLineWriteRepository;
    private static EpochMessageService messageService;
    private static DeliverOrderWriteRepository deliverOrderWriteRepository;
    private static DeliveryOrderDetailRepository deliveryOrderDetailRepository;
    //    private static CreditRepository creditRepository;
    private static CreditQueryService creditQueryService;
    private static OtsUnifiedInventoryService otsUnifiedInventoryService;
    private static OrderQueryRepository orderQueryRepository;
    private static  CustomSequenceAccessor customSequenceAccessor;
    private static OrderBackUpRepository orderBackUpRepository;
    static {
        customSequenceAccessor=SpringContextUtil.getBean(CustomSequenceAccessor.class);
        orderWriteRepository = SpringContextUtil.getBean(OrderWriteRepository.class);
        orderLineWriteRepository = SpringContextUtil.getBean(OrderLineWriteRepository.class);
        messageService = SpringContextUtil.getBean(EpochMessageService.class);
        deliverOrderWriteRepository = SpringContextUtil.getBean(DeliverOrderWriteRepository.class);
        deliveryOrderDetailRepository = SpringContextUtil.getBean(DeliveryOrderDetailRepository.class);
        creditQueryService = SpringContextUtil.getBean(CreditQueryService.class);
        otsUnifiedInventoryService = SpringContextUtil.getBean(OtsUnifiedInventoryService.class);
        orderQueryRepository = SpringContextUtil.getBean(OrderQueryRepository.class);
        orderBackUpRepository = SpringContextUtil.getBean(OrderBackUpRepository.class);
    }

    public static OrderWriteEntity of(OrderSDO orderSDO) {
        OrderWriteEntity orderWriteEntity = new OrderWriteEntity();
        orderWriteEntity.orderSDO = orderSDO;
        return orderWriteEntity;
    }

    @FunctionInvoker
    public static Result checkStockAndCredit(OrderSDO orderSDO) {
        Map<String,String> features = orderSDO.getFeatures();
        //退货订单不进行库存和信贷校验
        if (SetOrderTag.RETURN.equals(orderSDO.getOrderTag()) || (features != null && features.get(SaleOrderConstants.PUSH_COUNT) != null )){
            return Result.success(null);
        }

        //校验库存
        GetListWarehouseStockRequest getRequest = new GetListWarehouseStockRequest();
        getRequest.setWarehouseAreaId(orderSDO.getWareHouseCode());
        getRequest.setType("1");
        for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
            String scItemId = orderLineSDO.getScItemSDO().getScItemId();
            getRequest.setGoodsId(scItemId);
            Result<List<WarehouseInventory>> listWarehouseStock = otsUnifiedInventoryService.getListWarehouseStock(getRequest);
            if (CollectionUtils.isEmpty(listWarehouseStock.getResult())) {
//                throw new FunctionException("OTS-05-001-10-16-007");
                return Result.fail(null, "仓库中未查到对应货品的库存数据");
            }
            WarehouseInventory warehouseInventory = listWarehouseStock.getResult().get(0);
            //销售数量
            BigDecimal quantity = new BigDecimal(orderLineSDO.getScItemSDO().getQuantity());
            if (null == warehouseInventory.getAvailableQuantityFormat()) {
                return Result.fail(null, "库存不足");
            }
            //库存数量
            BigDecimal availableQuantityBigDecimal = new BigDecimal(warehouseInventory.getAvailableQuantityFormat());
            if (StringUtils.isBlank(orderLineSDO.getScItemSDO().getUnitConvert())) {
                log.error("库存不足 订单数量 = {}", quantity);
                log.error("商品：{}", JSONObject.toJSON(orderLineSDO.getScItemSDO()));
                return Result.fail(null, "该商品没有单位转换关系");
            }
            BigDecimal availableQuantity = availableQuantityBigDecimal.multiply(new BigDecimal(orderLineSDO.getScItemSDO().getUnitConvert()));
            if (quantity.compareTo(availableQuantity) > 0) {
                log.error("库存不足 订单数量 = {}", quantity);
                log.error("库存不足 库存数量 = {}", availableQuantity);
                return Result.fail(null, "库存不足");
            }
        }
        return Result.success(null);
        //需求变更，去除信贷校验，由015接口展示SAP信贷结果
//        //人工开关 todo 后续需要去除这个逻辑
//        if ("不检查".equals(orderSDO.getRemark())) {
//            return Result.success(null);
//        }
//        QueryCreditRequest request = new QueryCreditRequest();
//        request.setOrganizationCode(orderSDO.getOrganizationCode());
//        request.setChannelCode(orderSDO.getChannelCode());
//        request.setItemGroupCode(orderSDO.getProductGroupCode());
//        request.setCustomerCode(orderSDO.getCustomerCode());
//        request.setSaleOrderId(orderSDO.getId());
//        log.info("订单信贷查询入参：" + JSON.toJSONString(request));
//        Result<CreditReponse> result = creditQueryService.queryCreditBalance(request);
//        log.info("订单信贷查询结果：" + JSON.toJSONString(result));
//        CreditReponse response = result.getResult();
//        if (!result.isSuccess() || response == null) {
//            //接口异常直接跳过，不进行校验
//            return Result.fail(null, result.getMessage());
//        }
//        if (response.getRiskType() != null) {
//            Long totalFee = orderSDO.getOrderLineSDOS().stream().mapToLong(o -> {
//                return o.getShouldPayFee() == null ? 0L : o.getShouldPayFee();
//            }).sum();
//
//            Long creditFee = 0L;
//            try {
//                creditFee= MoneyUtil.formatRoundLong(response.getBalance());
//            }catch (Exception e){
//                log.error("信贷数据有问题, response = "+JSON.toJSONString(response),e);
////                return Result.fail("","信贷数据有问题");
//            }
//
//
//            if (CreditRiskType.A01.getType().equals(response.getRiskType()) && StringUtils.isBlank(response.getCreditFlag())) {
//                if (totalFee > creditFee) {
//                    return Result.fail("006", "信贷余额不足");
//                }
//            }
//            if (CreditRiskType.A02.getType().equals(response.getRiskType())) {
//                if (/*StringUtils.isBlank(response.getBalance()) && */("N".equals(response.getCreditFlag()))) {
//                    return Result.fail("006", "超账期/信贷检查不通过");
//                }
//            }
//            if (CreditRiskType.A03.getType().equals(response.getRiskType())) {
//                if (("N".equals(response.getCreditFlag()))) {
//                    if (totalFee > creditFee) {
//                        return Result.fail("006", "信贷检查不通过");
//                    }
//                }
//            }
//        }
//        return Result.success(null, result.getMessage());
    }



    /**
     * 保存销售订单
     * 预报单生成调用
     *
     * @return
     */
    @FunctionInvoker
    public List<BatchCreateOrderResponse> batchSave() {
        try {
            Integer num = 0;
            //存在sap单号无需校验直接创建订单
            if (StringUtils.isNotBlank(orderSDO.getOuterOrderId())) {
                String orderId = orderWriteRepository.saveOrder(orderSDO);
                orderSDO.setId(orderId);
                if (SetOrderTag.EXCHANGE.equals(orderSDO.getOrderTag())) {
                    //换货集合
                    List<OrderLineSDO> exchangeList = new ArrayList<>();
                    //退货集合
                    List<OrderLineSDO> returnList = new ArrayList<>();
                    if (CollectionUtils.isEmpty(orderSDO.getOrderLineSDOS())) {
                        throw new FunctionException("OTS-05-001-10-16-039");
                    }
                    for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
                        if (StringUtils.isNotBlank(orderLineSDO.getReturnCharacter()) && RETURN_FLAG.equals(orderLineSDO.getReturnCharacter())) {
                            returnList.add(orderLineSDO);
                        }else {
                            exchangeList.add(orderLineSDO);
                        }
                    }
                    if (CollectionUtils.isEmpty(exchangeList)) {
                        throw new FunctionException("OTS-05-001-10-16-037");
                    }

                    for(OrderLineSDO orderLineSDO : exchangeList){
                        num = ++num * Integer.parseInt(FIXED_VALUE);
                        orderLineSDO.setMainOrderId(orderId);
                        orderLineSDO.setSyncVersion(0);
                        orderLineSDO.setMainOrderBizId(orderSDO.getOrderBizId());
                        orderLineSDO.setSerialNumber(String.valueOf(num));
                        orderLineSDO.setOrderLineTag(SetOrderTag.EXCHANGE);
                        num = num / Integer.parseInt(FIXED_VALUE);
                    }
                    Map<String, OrderLineSDO> orderLineSDOMap = exchangeList.stream().collect(Collectors.toMap(orderLineSDO -> orderLineSDO.getScItemSDO().getScItemOutCode(), o -> o));

                    if (CollectionUtils.isEmpty(returnList)) {
                        throw new FunctionException("OTS-05-001-10-16-038");
                    }
                    List<OrderLineSDO> orderLineSDOS = new ArrayList<>();

                    for (OrderLineSDO orderLineSDO : returnList){
                        if (Objects.nonNull(orderLineSDO.getScItemSDO()) && StringUtils.isNotBlank(orderLineSDO.getScItemSDO().getScItemOutCode())) {
                            OrderLineSDO orderLineSDO1 = orderLineSDOMap.get(orderLineSDO.getScItemSDO().getScItemOutCode());
                            orderLineSDOS.add(orderLineSDO1);
                            if (Objects.nonNull(orderLineSDO1)) {
                                orderLineSDO.setMainOrderId(orderId);
                                orderLineSDO.setSyncVersion(0);
                                orderLineSDO.setSerialNumber((Integer.parseInt(orderLineSDO1.getSerialNumber()) + 1) + "");
                                orderLineSDO.setMainOrderBizId(orderSDO.getOrderBizId());
                                orderLineSDO.setOrderLineTag(SetOrderTag.RETURN);
                                orderLineSDOS.add(orderLineSDO);
                            }
                        }
                    }
                    if (CollectionUtils.isNotEmpty(orderLineSDOS)) {
                        for (OrderLineSDO orderLineSDO :orderLineSDOS){
                            String s = orderLineWriteRepository.batchCreateOrderLine(orderLineSDO);
                            orderLineSDO.setId(s);
                        }
                    }
                }else {
                    for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
                        num = ++num * Integer.parseInt(FIXED_VALUE);
                        orderLineSDO.setMainOrderId(orderId);
                        orderLineSDO.setSyncVersion(0);
                        orderLineSDO.setMainOrderBizId(orderSDO.getOrderBizId());
                        orderLineSDO.setSerialNumber(String.valueOf(num));
                        String s = orderLineWriteRepository.batchCreateOrderLine(orderLineSDO);
                        orderLineSDO.setId(s);
                        num = num / Integer.parseInt(FIXED_VALUE);
                    }
                }
                List<BatchCreateOrderResponse> responses = new ArrayList<>();
                BatchCreateOrderResponse response = new BatchCreateOrderResponse();
                response.setOrderId(orderId);
                responses.add(response);

                // sap发送订单创建消息
                TradeMessageSDO tradeMessageSDO = new TradeMessageSDO();
                tradeMessageSDO.setOrderSDO(orderSDO);
                String message = JSON.toJSONString(tradeMessageSDO);
                Map<String, String> map = new HashMap<>();
                map.put("_CZ_KEY", BcOtsConstants.TENANT_ID());
                log.info("SaleOrderSapCreated orderId = " + orderSDO.getId() + ", message = " + message + ",map = " + JSON.toJSONString(map) + " start");
                messageService.sendMessage("sale_order_message", "CR_SALEORDER", "SaleOrderSapCreated", orderSDO.getOrderBizId(), message,map);
                log.info("SaleOrderSapCreated order message = " + message + "end");
                return responses;
            }

            if (orderSDO.getOrderBizId() == null ){
                String nextStringSequence = customSequenceAccessor.getNextStringSequence("ots_b2b_trade_center", "saleOrderSequence");
                orderSDO.setOrderBizId(nextStringSequence);
            }
            Result flag = checkStockAndCredit(orderSDO);
            Date date = new Date();
            Map<String, String> features = orderSDO.getFeatures();
            if (MapUtils.isEmpty(features)) {
                features = new HashMap<>();
            }
//            BatchCreateOrderResponse response = new BatchCreateOrderResponse();

            this.orderSDO.setStatus(OrderStatus.PUSHING.getCode());

//            features.put(SaleOrderConstants.EXT_MESSAGE, flag.getMessage());
            if (!flag.isSuccess()) {
                this.orderSDO.setStatus(OrderStatus.STAY_PUSH.getCode());
                features.put(SaleOrderConstants.EXT_MESSAGE,flag.getMessage());
            }

            this.orderSDO.setFeatures(features);
            this.orderSDO.setSyncVersion(0);
            // TODO 暂时固定值  等预报传
            this.orderSDO.setOrderTag(orderSDO.getOrderTag() == null ? "normal" : orderSDO.getOrderTag());
            orderSDO.setGmtCreate(date);
            orderSDO.setGmtModified(date);
            String orderId = orderWriteRepository.saveOrder(this.orderSDO);
            orderSDO.setId(orderId);
            String forecastOrderId = "";
            Integer quantityList = 0;
            List<BatchCreateOrderResponse> batchCreateOrderResponses = new ArrayList<>();
            for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
                //num = ++num * Integer.parseInt(FIXED_VALUE);
                orderLineSDO.setMainOrderId(orderId);
                orderLineSDO.setSyncVersion(0);
                orderLineSDO.setMainOrderBizId(orderSDO.getOrderBizId());
                // TODO 暂时固定值  等预报传
                orderLineSDO.setOrderLineTag(SetOrderTag.NORMAL);
                orderLineSDO.setGmtCreate(date);
                orderLineSDO.setGmtModified(date);
                //orderLineSDO.setSerialNumber(String.valueOf(num));
                String orderLineId = orderLineWriteRepository.batchCreateOrderLine(orderLineSDO);
                orderLineSDO.setId(orderLineId);
                forecastOrderId = orderLineSDO.getFrontOrderLineId();
                quantityList = orderLineSDO.getScItemSDO().getQuantity();
                Map<String, String> featuresLine = orderLineSDO.getFeatures();
                //不是赠品的信息 返回预报信息  更新预报状态
                if (!(MapUtils.isNotEmpty(featuresLine) && ("gift").equals(String.valueOf(featuresLine.get("giftFlag"))))) {
                    BatchCreateOrderResponse response = new BatchCreateOrderResponse();
                    response.setOrderId(orderId);
                    response.setOrderBizId(orderSDO.getOrderBizId());
                    response.setForecastOrderLineId(forecastOrderId);
                    response.setPredictReplyAmount(quantityList);
                    response.setMessage(flag.getMessage());
                    //num = num / Integer.parseInt(FIXED_VALUE);
                    batchCreateOrderResponses.add(response);
                }

            }

//            if (orderSDO.getDeliverOrderSDO() != null) {
//                DeliverOrderSDO deliverOrderSDO = orderSDO.getDeliverOrderSDO();
//                deliverOrderSDO.setOrderId(orderId);
//                deliverOrderSDO.setSyncVersion(0);
//                deliverOrderSDO.setDeliveryStatus(OrderStatus.BEFORE_DELIVERY.getCode());
//                String s = deliverOrderWriteRepository.create(deliverOrderSDO);
//            }
            /*if (CollectionUtils.isNotEmpty(deliverOrderSDO.getDeliveryOrderDetailSDOS())) {
                for (DeliveryOrderDetailSDO deliveryOrderDetailSDO : deliverOrderSDO.getDeliveryOrderDetailSDOS()) {
                    deliveryOrderDetailSDO.setDeliveryOrderId(s);
                    deliveryOrderDetailSDO.setDeliveryStatus(OrderStatus.BEFORE_DELIVERY.getCode());
                    deliveryOrderDetailRepository.Create(deliveryOrderDetailSDO);
                }
            }*/
            TradeMessageSDO tradeMessageSDO = new TradeMessageSDO();
            tradeMessageSDO.setOrderSDO(orderSDO);
            String message = JSON.toJSONString(tradeMessageSDO);
            Map<String, String> map = new HashMap<>();
            map.put("_CZ_KEY", BcOtsConstants.TENANT_ID());
            log.info("orderId = " + orderSDO.getId() + ", message = " + message + ",map = " + JSON.toJSONString(map) + " start");
            if (flag.isSuccess()) {
                messageService.sendMessage("sale_order_message", "CR_SALEORDER", "SaleCreated", orderSDO.getOrderBizId(), message,map);
            }
            log.info("batchSave order message = " + message + "end");
            return batchCreateOrderResponses;
        } catch (Exception e) {
            log.error("batchSave order exception ",e);
            throw new FunctionException(e.getMessage());
        }
    }

    /**
     * 页面提交操作
     *
     * @return
     */
    @EpochTransactional(appCode="ots_b2b_trade_center", dataSourceCode = "cr_ots", dataSourceType = "app")
    public Result<Boolean> submit() {
//        Result result = checkStock(orderSDO);
//        if (!result.isSuccess()) {
//            this.orderSDO.setStatus(OrderStatus.STAY_PUSH.getCode());
//            return Result.fail(null,"库存不足");
//        }

        Result flag = checkStockAndCredit(orderSDO);
        Map<String, String> features = orderSDO.getFeatures();
        if (MapUtils.isEmpty(features)) {
            features = new HashMap<>();
        }

        if (this.orderSDO.getStatus() != 2) {
            this.orderSDO.setStatus(OrderStatus.BEFORE_SUBMIT.getCode());
        }
        //todo 已推送
//        if (orderSDO.getOrderTag().equals("return")) {
//            this.orderSDO.setStatus(OrderStatus.WAIT_RECEIVING.getCode());
//        } else if (orderSDO.getOrderTag().equals("exchange")) {
//            this.orderSDO.setStatus(OrderStatus.WAIT_HANDLE.getCode());
//        } else {
            this.orderSDO.setStatus(OrderStatus.PUSHING.getCode());
//        }

        features.put(SaleOrderConstants.EXT_MESSAGE, flag.getMessage());
        if (!flag.isSuccess()) {
            if ("006".equals(flag.getErrorCode())) {
                // 信用贷校验不通过 改为待推送状态
                this.orderSDO.setStatus(OrderStatus.STAY_PUSH.getCode());
                orderSDO.setFeatures(features);
                orderWriteRepository.updateOrder(orderSDO);
            }
            return Result.fail("006", flag.getMessage());
//            features.put(SaleOrderConstants.EXT_MESSAGE,flag.getMessage());
        }
        orderSDO.setFeatures(features);
        orderWriteRepository.updateOrder(orderSDO);


        boolean returnFlag = false;
//        Integer num = 0;
        List<OrderLineSDO> copyList = new ArrayList<>();
        for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
            orderLineSDO.setStatus(OrderStatus.PUSHING.getCode());
            //换货订单
            if ("exchange".equals(orderLineSDO.getOrderLineTag()) && orderSDO.getOrderTag().equals("exchange")) {
                OrderLineSDO copy = new OrderLineSDO();
                BeanUtils.copyProperties(orderLineSDO, copy);
                copy.setId(null);
                copy.setOrderLineTag("return");
                copy.setSerialNumber((Integer.parseInt(orderLineSDO.getSerialNumber()) + 1) + "");
                copyList.add(copy);
            }
            if ("return".equals(orderLineSDO.getOrderLineTag())) {
                returnFlag = true;
            }
//            num = Math.max(num, Integer.parseInt(orderLineSDO.getSerialNumber()));
            orderLineWriteRepository.modifyOrderLine(orderLineSDO);
        }

        if (CollectionUtils.isNotEmpty(copyList) && !returnFlag) {
            for (OrderLineSDO orderLineSDO : copyList) {
//                orderLineSDO.setSerialNumber(String.valueOf((++num)));
                String lineId = orderLineWriteRepository.batchCreateOrderLine(orderLineSDO);
                orderLineSDO.setId(lineId);
            }
            orderSDO.getOrderLineSDOS().addAll(copyList);
        }

//        DeliverOrderSDO deliverOrderSDO = orderSDO.getDeliverOrderSDO();
//        deliverOrderSDO.setOrderId(orderSDO.getId());
//        deliverOrderSDO.setSyncVersion(0);
//        deliverOrderSDO.setDeliveryStatus(OrderStatus.BEFORE_DELIVERY.getCode());
//        String s = deliverOrderWriteRepository.create(deliverOrderSDO);
        /*for (DeliveryOrderDetailSDO deliveryOrderDetailSDO : deliverOrderSDO.getDeliveryOrderDetailSDOS()) {
            deliveryOrderDetailSDO.setDeliveryOrderId(s);
            deliveryOrderDetailSDO.setDeliveryStatus(OrderStatus.BEFORE_DELIVERY.getCode());
            deliveryOrderDetailRepository.Create(deliveryOrderDetailSDO);
        }*/

        TradeMessageSDO tradeMessageSDO = new TradeMessageSDO();
        tradeMessageSDO.setOrderSDO(orderSDO);
        String message = JSON.toJSONString(tradeMessageSDO);
        Map<String, String> map = new HashMap<>();
        map.put("_CZ_KEY", BcOtsConstants.TENANT_ID());
        log.info("orderId = " + orderSDO.getId() + ", message = " + message + ",map = " + JSON.toJSONString(map) + " start");
        if (flag.isSuccess()) {
            Boolean aBoolean = messageService.sendMessage("sale_order_message", "CR_SALEORDER", "SaleCreated", orderSDO.getOrderBizId(), message, map);
            if (!aBoolean) {
                log.error("OrderWriteEntity$submitMQ_fail");
            }
        }
        log.info("submit order message = " + message);
        return Result.success(true);
    }

    @EpochTransactional(appCode="ots_b2b_trade_center", dataSourceCode = "cr_ots", dataSourceType = "app")
    public Result<Boolean> cancelOrder() {
        orderSDO.setStatus(OrderStatus.CANCELLED.getCode());
        orderWriteRepository.updateOrder(this.orderSDO);
        if (CollectionUtils.isNotEmpty(orderSDO.getOrderLineSDOS())) {
            for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
                orderLineSDO.setStatus(OrderStatus.CANCELLED.getCode());
                orderLineWriteRepository.modifyOrderLine(orderLineSDO);
            }
        }
        TradeMessageSDO tradeMessageSDO = new TradeMessageSDO();
        tradeMessageSDO.setOrderSDO(orderSDO);
        String message = JSON.toJSONString(tradeMessageSDO);
        Map<String, String> map = new HashMap<>();
        map.put("_CZ_KEY", BcOtsConstants.TENANT_ID());
        messageService.sendMessage("sale_order_message", "CR_SALEORDER", "SaleCanceled", orderSDO.getOrderBizId(), message, map);
        return Result.success(true);
    }

    @FunctionInvoker
    @EpochTransactional(appCode="ots_b2b_trade_center", dataSourceCode = "cr_ots", dataSourceType = "app")
    public Result<Boolean> modify() {
        List<Integer> serialNumberList = new ArrayList<>();
        for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
            if (StringUtils.isNotBlank(orderLineSDO.getSerialNumber())) {
                String serialNumber = orderLineSDO.getSerialNumber();
                serialNumberList.add(Integer.parseInt(serialNumber));
            }
        }
        Integer num = 0;
        if (CollectionUtils.isNotEmpty(serialNumberList)) {
            num = serialNumberList.stream().reduce(Integer::max).get() / Integer.parseInt(FIXED_VALUE);
        }

        List<String> ids = new ArrayList<>();
        for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
            if (StringUtils.isNotBlank(orderLineSDO.getRefuseReasonCode())) {
                orderLineSDO.setStatus(OrderStatus.COMPLETED.getCode());
                ids.add(orderLineSDO.getId());
            }
            if (StringUtils.isNotBlank(orderLineSDO.getId())) {
                orderLineWriteRepository.modifyOrderLine(orderLineSDO);
            } else {
                num = ++num * Integer.parseInt(FIXED_VALUE);
                orderLineSDO.setSerialNumber(String.valueOf(num));
                orderLineSDO.setMainOrderId(orderSDO.getId());
                orderLineSDO.setStatus(OrderStatus.BEFORE_DELIVERY.getCode());
                orderLineSDO.setSyncVersion(0);
                orderLineWriteRepository.save(orderLineSDO);
                num = num / Integer.parseInt(FIXED_VALUE);
            }
        }
        if (CollectionUtils.isNotEmpty(ids) && ids.size() == orderSDO.getOrderLineSDOS().size()) {
            orderSDO.setStatus(OrderStatus.COMPLETED.getCode());
        }
        orderWriteRepository.updateOrder(orderSDO);
        return Result.success(true);
    }

    @Transactional(rollbackFor = RuntimeException.class)
    public String save() {
        orderSDO.setStatus(OrderStatus.BEFORE_SUBMIT.getCode());
        orderSDO.setSyncVersion(0);
        String id = orderWriteRepository.saveOrder(this.orderSDO);
        return id;
    }

    /**
     * 修改销售订单状态
     */
    public Boolean modifyStatus() {
        return orderWriteRepository.updateOrderStatus(this.orderSDO);
    }

    /**
     * 备份并删除销售订单
     */
    public void deleteOrder() {
        orderBackUpRepository.deleteOrder(orderSDO);
    }

    /**
     * 校验库
     */
//    private Result checkStock(OrderSDO orderSDO) {
//        QueryInventoryRequest query = new QueryInventoryRequest();
//        query.setType(TYPE);
//        query.setWarehouseAreaId(orderSDO.getWareHouseCode());
//         for(OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()){
//            String scItemId = orderLineSDO.getScItemSDO().getScItemId();
//            query.setGoodsId(scItemId);
//            QueryInventoryResponse queryInventoryResponse = forecastOrderWriteService.queryInventory(query);
//             Integer availableQuantityOne = 0;
//             if (!ObjectUtils.allNotNull(queryInventoryResponse.getResult())) {
//                 return Result.fail(null,"库存不足");
//             }
//            if (ObjectUtils.allNotNull(queryInventoryResponse.getResult())) {
//                Map result = (Map) queryInventoryResponse.getResult();
//                if (ObjectUtils.allNotNull(result.get("availableQuantity"))) {
//                    Double availableQuantity = Double.valueOf((Double) result.get("availableQuantity"));
//                    availableQuantityOne = (int) availableQuantity.doubleValue();
//                    Integer quantity = orderLineSDO.getScItemSDO().getQuantity();
//                    if (quantity > availableQuantityOne) {
//                        return Result.fail(null ,"库存不足");
//                    }
//                }
//            }
//        }
//        return Result.success(null,"库存满足");
//    }
}
